#pragma once

#include "utility.h"
#include "deque.h"

namespace qyc
{
    template<class T, class Container = deque<T>>
    class stack
    {
        typedef T data_type;
        typedef data_type& reference;
        typedef const data_type& const_reference;
        typedef data_type* pointer;
        typedef const data_type* const_pointer;
        typedef stack<T, Container> self;
    public:
        void push(const data_type& data)
        {
            _con.push_back(data);
        }
        void push(data_type&& data)
        {
            _con.push_back(qyc::forward<data_type>(data));
        }
        template<class... Args>
        void emplace(Args&&... args)
        {
            _con.emplace_back(args...);
        }
        void pop()
        {
            _con.pop_back();
        }

        size_t size() const
        {
            return _con.size();
        }
        bool empty() const
        {
            return _con.empty();
        }
        
        reference top()
        {
            return _con.back();
        }
        const_reference top() const
        {
            return _con.back();
        }
        void swap(self& right)
        {
            _con.swap(right._con);
        }
    private:
        Container _con;
    };
}